//
//  TWSmallVideoPlayerView.swift
//  EyepetizerImitative
//
//  Created by 田伟 on 2017/4/6.
//  Copyright © 2017年 个人. All rights reserved.
//  小图播放器 因为释放内存问题暂时没有使用


// MARK:- 小图播放器 因为释放内存问题暂时没有使用



import UIKit
import SnapKit
import AVFoundation

class TWSmallVideoPlayerView: UIView {

    // 最底层的View
    fileprivate lazy var backView : UIView = UIView()
    fileprivate lazy var backImageView : UIImageView = UIImageView()
    
    // 上部
    fileprivate lazy var topView : UIView = UIView()                                                                    // 顶部的View
    fileprivate lazy var likeButton: UIButton = UIButton()
    fileprivate lazy var shareButton: UIButton = UIButton()
    fileprivate lazy var reviewButton: UIButton = UIButton()
    // 中间
    fileprivate lazy var playButton : UIButton = UIButton()                                                             // 中间View中的播放按钮
    // 已播时间和剩余时间的label
    fileprivate lazy var timeLabel : UILabel = UILabel()
    // 底部
    fileprivate lazy var bottomView : UIView = UIView()                                                                 // 底部的View
    fileprivate lazy var fullScreenButton : UIButton = UIButton()                                                       // 底部View中的全屏按钮
    fileprivate lazy var progressView : UIProgressView = UIProgressView()                                               // 底部View中的缓存进度条
    fileprivate lazy var slider : UISlider = UISlider()                                                                 // 底部View中的播放进度条
    
    // 定时器--自动消失View
    fileprivate lazy var autoDismissTimer : Timer = Timer()
    
    // MARK:- 属性
    var player : AVPlayer?                                                                                              // 播放器
    var playerLayer : AVPlayerLayer?                                                                                    // 播放器需要的layer
    var playerItem : AVPlayerItem?                                                                                      // 播放器属性对象
    
    var isDragSlider : Bool = false                                                                                     // 是否拖动Slider
    
    var palyModel : TWItemModel?{
        didSet {
            guard let palyModel = palyModel else {
                return
            }
            // 设置占位图像
            videobgImageUrl = URL(string: (palyModel.cover?.detail)!)
            if let _ = videobgImageUrl {
                setupBgImageView()
            }
            
            // 初始化播放器
            videoUrl = URL(string: palyModel.playUrl!)
            if let videoUrl = videoUrl {
                
                playerItem = AVPlayerItem(url: videoUrl)
                // 监听
                playerItem?.addObserver(self, forKeyPath: "status", options: .new, context: nil)
                playerItem?.addObserver(self, forKeyPath: "loadedTimeRanges", options: .new, context: nil)
                
                player = AVPlayer(playerItem: playerItem)
                playerLayer = AVPlayerLayer(player: player)
                
                // 初始化播放器的Layer
                playerLayer = AVPlayerLayer(player: player)
                // layer的方向宽和高对调
                playerLayer!.frame = frame
                // 等比例拉伸，会裁剪
                playerLayer!.videoGravity = AVLayerVideoGravityResizeAspectFill
                // 把layer加到底部的view上
                backView.layer.insertSublayer(playerLayer!, at: 0)
                
            }
        }
    }
    var videoUrl : URL?
    var videobgImageUrl : URL?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupBackView()
        setupTopView()
        setupMiddleView()
        setupBottomView()
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    deinit {
        TWLog(message: "播发器内存释放掉了⭐️")
        playerLayer?.removeFromSuperlayer()
        player = nil
        playerLayer = nil
        playerItem?.removeObserver(self, forKeyPath: "loadedTimeRanges")
        playerItem?.removeObserver(self, forKeyPath: "status")
    }
    // 退出播放器
    func dismissSmallVideoPlayer(){
        autoDismissTimer.invalidate()
//        player?.currentItem?.cancelPendingSeeks()
//        player?.currentItem?.asset.cancelLoading()
        playerItem?.removeObserver(self, forKeyPath: "loadedTimeRanges")
        playerItem?.removeObserver(self, forKeyPath: "status")
//        player = nil
//        playerLayer = nil
//        playerItem = nil
    }
}

// MARK:- 初始化播放器
extension TWSmallVideoPlayerView {
//    fileprivate func initPlayer(url : URL){
//        
//        // 把通知，观察者全部移除，player 置为nil，然后重新创建。
//        player?.pause()
//        dismissSmallVideoPlayer()
//        
//        let playerItem = AVPlayerItem(url: url)
//        // 监听
//        playerItem.addObserver(self, forKeyPath: "status", options: .new, context: nil)
//        playerItem.addObserver(self, forKeyPath: "loadedTimeRanges", options: .new, context: nil)
//        
//        
//        player?.replaceCurrentItem(with: playerItem)
//        // 初始化播放器的Layer
//        playerLayer = AVPlayerLayer(player: player)
//        // layer的方向宽和高对调
//        playerLayer!.frame = frame
//        // 等比例拉伸，会裁剪
//        playerLayer!.videoGravity = AVLayerVideoGravityResizeAspectFill
//        // 把layer加到底部的view上
//        backView.layer.insertSublayer(playerLayer!, at: 0)
//    }
}

// MARK:- 搭建UI界面
extension TWSmallVideoPlayerView {
    // 处理背景视图
    fileprivate func setupBackView(){
        backView.frame = frame
        backView.backgroundColor = UIColor.black
        let tap = UITapGestureRecognizer(target: self, action: #selector(backViewSingleTap))
        backView.addGestureRecognizer(tap)
        addSubview(backView)
    }
    fileprivate func setupBgImageView(){
        backImageView.frame = backView.frame
        backImageView.sd_setImage(with: videobgImageUrl)
        backImageView.contentMode = .scaleToFill
        backView.addSubview(backImageView)
    }
    // 设置顶部View
    fileprivate func setupTopView(){
        topView.backgroundColor = UIColor.black.withAlphaComponent(0.8)
        backView.addSubview(topView)
        topView.snp.makeConstraints { (make) in
            make.top.equalTo(backView)
            make.left.right.equalTo(backView)
            make.height.equalTo(54)
        }
        reviewButton.setImage(UIImage(named: "Action_review_44x44_"), for: .normal)
        reviewButton.addTarget(self, action: #selector(reviewButtonDidClick), for: .touchUpInside)
        reviewButton.showsTouchWhenHighlighted = true
        topView.addSubview(reviewButton)
        reviewButton.snp.makeConstraints { (make) in
            make.top.right.equalTo(topView).offset(10)
            make.height.width.equalTo(44)
        }
        shareButton.setImage(UIImage(named: "Action_Share_44x44_"), for: .normal)
        shareButton.addTarget(self, action: #selector(shareButtonDidClick), for: .touchUpInside)
        shareButton.showsTouchWhenHighlighted = true
        topView.addSubview(shareButton)
        shareButton.snp.makeConstraints { (make) in
            make.top.equalTo(topView).offset(10)
            make.right.equalTo(reviewButton.snp.left)
            make.height.width.equalTo(44)
        }
        likeButton.setImage(UIImage(named: "Action_Like_44x44_"), for: .normal)
        likeButton.addTarget(self, action: #selector(likeButtonDidClick), for: .touchUpInside)
        likeButton.showsTouchWhenHighlighted = true
        topView.addSubview(likeButton)
        likeButton.snp.makeConstraints { (make) in
            make.top.equalTo(topView).offset(10)
            make.right.equalTo(shareButton.snp.left)
            make.height.width.equalTo(44)
        }
    }
    // 设置中间View
    fileprivate func setupMiddleView(){
        playButton.setImage(UIImage(named: "action_player_play_80x80_"), for: .normal)
        playButton.addTarget(self, action: #selector(pauseOrPlayButtonClick), for: .touchUpInside)
        playButton.showsTouchWhenHighlighted = true
        backView.addSubview(playButton)
        playButton.snp.makeConstraints { (make) in
            make.centerX.centerY.equalTo(backView)
            make.height.width.equalTo(80)
        }
        timeLabel.textColor = UIColor.white
        timeLabel.font = UIFont.systemFont(ofSize: 17)
        timeLabel.textAlignment = .center
        backView.addSubview(timeLabel)
        timeLabel.snp.makeConstraints { (make) in
            make.top.equalTo(playButton.snp.bottom)
            make.centerX.equalTo(playButton)
            make.width.equalTo(TWScreenWidth)
        }
    }
    // 设置底部View
    fileprivate func setupBottomView(){
        bottomView.backgroundColor = UIColor.black.withAlphaComponent(0.6)
        backView.addSubview(bottomView)
        bottomView.snp.makeConstraints { (make) in
            make.left.bottom.right.equalTo(backView)
            make.height.equalTo(30)
        }
        fullScreenButton.setImage(UIImage(named: "fullscreen"), for: .normal)
        fullScreenButton.showsTouchWhenHighlighted = true
        fullScreenButton.addTarget(self, action: #selector(fullScreenButtonClick), for: .touchUpInside)
        backView.addSubview(fullScreenButton)
        fullScreenButton.snp.makeConstraints { (make) in
            make.right.equalTo(backView).offset(5)
            make.width.height.equalTo(50)
            make.bottom.equalTo(bottomView.snp.top)
        }
        slider.minimumValue = 0.0
        slider.value = 0.0
        slider.minimumTrackTintColor = UIColor.white
        slider.maximumTrackTintColor = UIColor.lightGray
        let image : UIImage = UIImage(named: "player_handle")!
        slider.setThumbImage(image, for: .normal)
        // 拖动滑块改变值
        slider.addTarget(self, action: #selector(sliderDragValueChange(slider:)), for: .valueChanged)
        // 点击进度条上的某个位置改变值
        slider.addTarget(self, action: #selector(sliderTapValueChange(slider:)), for: .touchUpInside)
        // 增加手势
        let sliderTap = UITapGestureRecognizer(target: self, action: #selector(touchSlider(tap:)))
        slider.addGestureRecognizer(sliderTap)
        bottomView.addSubview(slider)
        slider.snp.makeConstraints { (make) in
            make.left.equalTo(backView).offset(-6)
            make.right.equalTo(backView).offset(6)
            make.centerY.equalTo(bottomView)
        }
        progressView.trackTintColor = UIColor.white
        progressView.progressTintColor = UIColor.darkGray
        progressView.setProgress(0.0, animated: false)
        bottomView.addSubview(progressView)
        progressView.snp.makeConstraints { (make) in
            make.left.equalTo(slider)
            make.right.equalTo(slider)
            make.height.equalTo(5)
            make.centerY.equalTo(slider.snp.centerY).offset(1)
        }
        bottomView.sendSubview(toBack: progressView)
    }
}


// MARK:- 监听点击
extension TWSmallVideoPlayerView {
    // 监听播放器的变化属性
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        guard let playerItem = object as? AVPlayerItem else {
            return
        }
        if keyPath == "status" {
            if playerItem.status == .readyToPlay {
                backImageView.removeFromSuperview()
                pauseOrPlayButtonClick()
                // 最大值直接用sec，以前都是
                // CMTimeMake(帧数（slider.value * timeScale）, 帧/sec)
                slider.maximumValue = Float(CMTimeGetSeconds(playerItem.duration))
                self.initTimer()
                // 启动定时器 5秒自动隐藏
                autoDismissTimer = Timer.init(timeInterval: 8.0, target: self, selector: #selector(autoDismissView), userInfo: nil, repeats: true)
                RunLoop.current.add(autoDismissTimer, forMode: .defaultRunLoopMode)
            } else {
                print("视频加载异常")
            }
        } else if keyPath == "loadedTimeRanges" {
            let timeInterval = availableDuration()
            let duration = playerItem.duration
            let durationTime = CMTimeGetSeconds(duration)
            // 给进度条赋值
            let progress = timeInterval / durationTime
            progressView.setProgress(Float(progress), animated: false)
        }
    }
    // 轻按背景视图backView
    @objc fileprivate func backViewSingleTap(){
        // 删除之前未执行的操作
        NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(autoDismissView), object: nil)
        // 这里点击会隐藏对应的View，那么之前的定时还开着，如果不关掉，就会可能重复
        autoDismissTimer.invalidate()       // 关掉定时器
        // 再重新打开定时器
        autoDismissTimer = Timer.init(timeInterval: 8.0, target: self, selector: #selector(autoDismissView), userInfo: nil, repeats: true)
        RunLoop.current.add(autoDismissTimer, forMode: .defaultRunLoopMode)
        // 更改UI
        UIView.animate(withDuration: 1.0) {
            if self.bottomView.alpha == 1 {
                self.bottomView.alpha = 0
                self.topView.alpha = 0
                self.playButton.alpha = 0
                self.timeLabel.alpha = 0
                self.fullScreenButton.alpha = 0
            } else if self.bottomView.alpha == 0 {
                self.bottomView.alpha = 1
                self.topView.alpha = 1
                self.playButton.alpha = 1
                self.timeLabel.alpha = 1
                self.fullScreenButton.alpha = 1
            }
        }
    }
    @objc fileprivate func reviewButtonDidClick(){
        print("reviewButtonDidClick")
    }
    @objc fileprivate func shareButtonDidClick(){
        print("shareButtonDidClick")
    }
    @objc fileprivate func likeButtonDidClick(){
        print("likeButtonDidClick")
    }
    @objc fileprivate func fullScreenButtonClick(){
        print("点击全屏播放")
    }
    @objc fileprivate func pauseOrPlayButtonClick(){
        if player?.rate != 1 {
            playButton.setImage(UIImage(named: "action_player_pause_80x80_"), for: .normal)
            player?.play()
        } else {
            playButton.setImage(UIImage(named: "action_player_play_80x80_"), for: .normal)
            player?.pause()
        }
    }
    // 进度条的滑块拖拽的时候调用,这个时候不更新视频进度
    @objc fileprivate func sliderDragValueChange(slider : UISlider){
        isDragSlider = true
    }
    // 点击调用  或者 拖拽完毕的时候调用
    @objc fileprivate func sliderTapValueChange(slider : UISlider){
        isDragSlider = false
        let cmtime = CMTime(seconds: Double(slider.value), preferredTimescale: (playerItem?.currentTime().timescale)!)
        player?.seek(to: cmtime)
    }
    // 点击事件的Slider
    @objc fileprivate func touchSlider(tap : UITapGestureRecognizer){
        let touch = tap.location(in: slider)
        let scale = touch.x / slider.bounds.size.width      // 根据点击的坐标计算对应的比例
        let duration = Float(CMTimeGetSeconds((playerItem?.duration)!))
        slider.value = duration * Float(scale)
        let cmtime = CMTime(seconds: Double(slider.value), preferredTimescale: (playerItem?.currentTime().timescale)!)
        player?.seek(to: cmtime)
        if player?.rate != 1 {               // 0.0 means "stopped", 1.0 means "play
            playButton.setImage(UIImage(named: "action_player_pause_80x80_"), for: .normal)
            player?.play()
        }
    }
    // 自动隐藏backView
    @objc private func autoDismissView(){
        if player?.rate == 0 {
            // 0表示暂停状态，不隐藏
        } else if player?.rate == 1 {// 1表示播放中
            if bottomView.alpha == 1 {
                UIView.animate(withDuration: 1.0, animations: {
                    self.bottomView.alpha = 0
                    self.topView.alpha = 0
                    self.playButton.alpha = 0
                    self.timeLabel.alpha = 0
                    self.fullScreenButton.alpha = 0
                })
            }
        }
    }
}

// MARK:- 自定义方法
extension TWSmallVideoPlayerView {
    // 调用plaer的对象进行UI更新
    fileprivate func initTimer(){
        let cmtime = CMTime(value: 1, timescale: 1)
        // 播放器用addPeriodicTimeObserverForInterval设定每隔1秒监控播放时间变化,每秒更新一次UI Slider
        player?.addPeriodicTimeObserver(forInterval: cmtime, queue: DispatchQueue.main) { [weak self] (_) in
            let now = CMTimeGetSeconds((self?.playerItem?.currentTime())!)               // 当前时间
            let duration = CMTimeGetSeconds((self?.playerItem?.duration)!)               // 总时间
            // 转成时间点
            let nowTime = self?.convertToTime(time: CGFloat(now))
            let timeDifference = CGFloat(duration - now)
            let remainTime = self?.convertToTime(time: timeDifference)
            self?.timeLabel.text = "\(nowTime!)" + " / " + "\(remainTime!)"
            // 不是拖拽中的话更新UI
            if !(self?.isDragSlider)! {
                self?.slider.value = Float(now)
            }
        }
    }
    // 将秒数转换成 00:00 的格式
    private func convertToTime(time : CGFloat) -> String{
        var timeStr : String = ""
        if time >= 3600 {
            // 超过一小时
            let hour = Int(time / 3600)
            let minutes = Int((time / 60).truncatingRemainder(dividingBy: 60))
            let seconds = Int(time.truncatingRemainder(dividingBy: 60))
            timeStr = String(format: "%02d:%02d:%02d", hour, minutes, seconds)
            return timeStr
        } else {
            let minutes = Int(time / 60)
            let seconds = Int(time.truncatingRemainder(dividingBy: 60))
            timeStr = String(format: "%02d:%02d", minutes, seconds)
            return timeStr
        }
    }
    // 计算缓冲进度
    fileprivate func availableDuration() -> TimeInterval {
        let loadedTimeRanges = playerItem?.loadedTimeRanges
        // 获取缓冲区域
        let timeRange = loadedTimeRanges?.first?.timeRangeValue
        // 开始的点
        let startSeconds = CMTimeGetSeconds((timeRange?.start)!)
        // 已缓存的时间点
        let durationSeconds = CMTimeGetSeconds((timeRange?.duration)!)
        // 计算缓冲总进度
        let result = startSeconds + durationSeconds
        return TimeInterval(result)
    }
}

// MARK:- 对外的方法
extension TWSmallVideoPlayerView {
    // 暂停播放
    func videoPause(){
        playButton.setImage(UIImage(named: "action_player_play_80x80_"), for: .normal)
        player?.pause()
    }
    // 开始播放
    func videoPay(){
        playButton.setImage(UIImage(named: "action_player_pause_80x80_"), for: .normal)
        player?.play()
    }
}

